<template>
  <div class="flex align-items-center">
    <template v-if="uploadType === 'list' || uploadType === 'single' ">
      <div class="flex flex-wrap">
        <div
          v-for="(item, index) in localFileList"
          :key="index"
          class="mr20p flex align-items-center"
        >
          <template v-if="!checkVisibleInDetail">
            <a
              style="white-space:nowrap"
              @click="$noticeWarning('抱歉，app端无法导出，请在系统电脑端进行导出')"
            >{{ item.fileName }}</a>
          </template>
          <template v-else>
            <a-popover
              v-if="item.percent === 100 && item.url"
              :key="item.fileId"
              placement="top"
            >
              <template slot="content">
                <a
                  style="white-space:nowrap"
                  :href="item.url"
                  target="_parent"
                >下载</a>
                <a-divider type="vertical" />
                <a
                  :key="item.fileId"
                  @click="$filePreview(item)"
                >查看</a>
              </template>
              <a>{{ item.fileName }} </a>
            </a-popover>
            <span v-else>{{ item.fileName }} </span>
          </template>
          <a-icon
            v-if="!disabled"
            style="cursor: pointer; margin-left: 6px"
            :type="item.percent === 100 && item.url ? 'close' : 'loading'"
            @click="deleteFile(item)"
          />
        </div>
      </div>
      <a-upload
        v-if="!disabled"
        :disabled="loading"
        :show-upload-list="false"
        :multiple="uploadType === 'list'"
        :before-upload="beforeUpload"
        @change="handleChanges"
      >
        <a-button
          v-if="localFileList.length < maxUploadCount && !disabled "
          @click="files = []"
        >
          <a-icon
            :type="loading ? 'loading' : 'plus'"
            style="color: #1890ff"
          />
          {{ uploadBtnText }}
        </a-button>
      </a-upload>
    </template>
    <template v-if="uploadType === 'image-list' || uploadType === 'image-single' ">
      <a-upload
        :disabled="disabled || loading"
        list-type="picture-card"
        :file-list="localFileList"
        :accept="accept + '.jpg, .gif, .png, .jpeg'"
        :remove="deleteFile"
        :multiple="uploadType === 'image-list'"
        :before-upload="beforeUpload"
        class="up-wrapper"
        @preview="handlePreview"
        @change="handleChanges"
      >
        <div
          v-if="localFileList.length < maxUploadCount && !disabled"
          class="up-div"
          @click="files = []"
        >
          <a-icon :type="loading ? 'loading' : 'plus'" />
          <div class="ant-upload-text" />
        </div>
      </a-upload>
      <!--      <img :src="localFileList[0].url" alt="" style="width: 400px;">-->
      <!-- 图片预览 -->
      <pre-view
        :preview-image="previewImage"
        :visible.sync="previewVisible"
      />
    </template>
  </div>
</template>
<script>
import { deleteFile, uploadFile } from '@/api'
import Vue from 'vue'
import PreView from '@/components/PreView'
import { checkVisibleInDetail } from '@/utils/util'
import debounce from 'lodash/debounce'

export default {
  name: 'BuploadVModel',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    // 文件类型
    uploadType: {
      type: String,
      default() {
        //list、single、image-single、image-list
        return 'list'
      }
    },
    uploadBtnText: {
      type: String,
      default: '上传文件'
    },
    maxUploadCount: {
      type: Number,
      default: 9
    },
    // 业务编码
    businessCode: {
      type: String,
      required: true
    },
    needChineseName: {
      type: Boolean,
      default: false
    },
    // 是否禁止上传
    disabled: {
      type: Boolean,
      default() {
        return false
      }
    },
    // 图片文件类型
    accept: {
      type: String,
      default() {
        return ''
      }
    },
    value: {
      type: [Array, Object],
      default() {
        return []
      }
    },
    test: {
      type: [Array, Object],
      default() {
        return []
      }
    }
  },
  components: {
    PreView
  },
  data() {
    return {
      checkVisibleInDetail: checkVisibleInDetail(this),
      previewImage: '',
      previewVisible: false,
      token: Vue.getAcloudProvider().getAccessToken(),
      loading: false,
      localFileList: [],
      // 一次最多10个
      num: 10,
      // 文件列表
      files: []
    }
  },
  watch: {
    value() {
      this.transform(true)
    }
  },
  created() {
    this.transform()
  },
  methods: {
    beforeUpload(info) {
      // const { size } = info
      // if (size / 1024 / 1024 > 500) {
      //   // 限制文件大小为500M
      //   this.$message.error('上传文件不可超出500M')
      //   return false
      // }
      return false
    },
    transform(clear = false) {
      if (clear) this.localFileList = []
      if (this.value instanceof Array) {
        this.value.forEach((item) => this.localFileList.push(this.transformItem(item)))
      }
      //  else {
      //   if (this.value && this.value.id) {
      //     this.localFileList.push(this.transformItem(this.value))
      //   }
      // }
    },
    transformItem(item) {
      // if (item.uid) return item
      const { id, fileName, fileId } = item
      return {
        ...item,
        uid: id,
        name: fileName,
        percent: 100,
        url: '/api/ycloud-file-center/oper/download?access_token=' + this.token + '&fileId=' + fileId
      }
    },
    /**
     * @description: 文件格式不对提示
     * @param {void}
     * @return {function}
     */
    imgDebounce: debounce(function () {
      return this.$noticeWarning('文件格式不对')
    }, 500),
    /**
     * @description: 文件上传防抖
     * @param {function}
     * @return {void}
     */
    fileChange: debounce(function () {
      this.handleUploadFun()
    }, 500),
    /**
     * @description: 接管文件上传
     * @param {object} info 文件对象
     * @return {void}
     */
    handleChanges(info) {
      // 图片删除直接返回并从列表中删除当前文件
      if (this.files.length + this.localFileList.length > info.fileList.length) {
        this.localFileList = this.localFileList.filter((el) => el.id !== info.file.id)
        return
      }
      let pass = true
      const { file } = info
      if (this.uploadType === 'image-list' || this.uploadType === 'image-single') {
        let suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
        if (!['jpg', 'gif', 'jpeg', 'png'].find((v) => v === suffix.toLocaleLowerCase())) {
          this.imgDebounce()
          pass = false
        }
      }
      if (pass) {
        this.files.push(file)
        this.fileChange()
      }
    },
    /**
     * @description: 判断及操作上传文件队列
     * @return {void}
     */
    async handleUploadFun() {
      let pass = true
      if (pass && this.localFileList.length + this.files.length > this.maxUploadCount) {
        pass = false
        this.$message.error(`最多上传${this.maxUploadCount}个文件！`)
        this.files = this.files.slice(0, this.maxUploadCount - this.localFileList.length)
      }
      if (this.multiple) {
        if (pass && this.files.length > this.num) {
          this.$message.error(`一次最多上传${this.num}个文件！`)
          this.files = this.files.slice(0, this.num)
        }
      }
      this.loading = true
      try {
        for (let i = 0; i < this.files.length; i++) {
          await this.uploadFun(this.files[i])
        }
        if (this.value instanceof Array) {
          console.log(this.localFileList)
          this.$emit('change', this.localFileList)
          this.$emit('getFileList', this.localFileList)
        } else {
          this.$emit('change', this.localFileList[0])
          this.$emit('getFileList', this.localFileList[0])
        }
      } catch (err) {
        console.log(err)
      } finally {
        this.files = []
        this.loading = false
      }
    },
    /**
     * @description: 上传函数拆分
     * @param {object} file 文件
     * @return {void}
     */
    uploadFun(file) {
      return new Promise(async (resolve, reject) => {
        // let fileName = file.name.substring(0, file.name.lastIndexOf('.'))
        const fb = new FormData()
        fb.append('file', file)
        fb.append('businessCode', this.businessCode)

        // if (this.uploadType === 'single' || this.uploadType === 'image-single') this.localFileList = []
        // this.localFileList.push({ uid: file.uid, name: fileName, fileName, percent: 0 })
        // let index = this.localFileList.length - 1

        let res = await uploadFile(fb)
        if (res.code === 200) {
          // this.$set(this.localFileList, index, this.transformItem(res.data))
          this.localFileList.push(this.transformItem(res.data))
        } else {
          // this.localFileList.splice(index, 1)
        }
        resolve()
      })
    },
    async deleteFile(record) {
      let index = this.localFileList.findIndex((v) => v.id === record.id)
      this.localFileList[index].percent = 99
      let commonId = record.originFileObj && record.originFileObj.commonId ? record.originFileObj.commonId : record.commonId
      this.loading = true
      let res = await deleteFile([commonId])
      if (res.data.code === this.SUCCESS_CODE) {
        let resIndex = this.localFileList.findIndex((v) => v.id === record.id)
        if (resIndex !== -1) this.localFileList.splice(resIndex, 1)
      } else {
        this.localFileList[index].percent = 100
      }
      this.loading = false
      if (this.value instanceof Array) {
        this.$emit('change', this.localFileList)
        this.$emit('getFileList', this.localFileList)
      } else {
        this.$emit('change', this.localFileList[0])
        this.$emit('getFileList', this.localFileList[0])
      }
    },
    async handlePreview(file) {
      if (!file.url && !file.preview) {
        file.preview = await this.getBase64(file.originFileObj)
      }
      this.previewImage = file.url || file.preview
      this.previewVisible = true
    },
    getBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = (error) => reject(error)
      })
    }
  }
}
</script>
<style lang="less" scoped>
@deep: ~'>>>';
.up-wrapper {
  @{deep}.ant-upload {
    position: relative;
  }
}
.up-div {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
